package br.com.dataphonebr;

import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.telephony.SmsManager;
import android.text.Html;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import br.com.dataphonebr.dao.impl.UsuarioDao;
import br.com.dataphonebr.service.CredentialsService;
import br.com.dataphonebr.service.GenericAdapterService;
import br.com.dataphonebr.service.IGenericService;
import br.com.dataphonebr.util.DataphoneAsyncTask;
import br.com.dataphonebr.util.Util;

public class GenericActivity<E> extends GenericPersistenceActivity<E> implements IGenericActivity<E>{
	
	protected static final String DUPLICATE = "DUPLICATE";
	protected static final String ENABLED = "ENABLED";
	protected Util util = new Util();
	protected CredentialsService credentialsService = new CredentialsService(this);
	protected GenericAdapterService<E> adapter;
	protected UsuarioDao usuarioDao;
	protected int dataSelected;
	protected AlertDialog alertDialog;
	protected AlertDialog alertYesNo;
	private Long id;
	private E instance;
	private Class<E> clazz;
	private Boolean finalize;
	private ListView listView;
	
	protected void editHidden(EditText edit){
		InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
		imm.hideSoftInputFromWindow(edit.getWindowToken(), 0);
		getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
	}
	
	protected CharSequence[] getOptionsAppointmentMenu(){
		CharSequence[] options = {getString(R.string.alert_edit_adm), getString(R.string.alert_duplicate_adm), getString(R.string.alert_remove_adm), getString(R.string.alert_cancel_adm), getString(R.string.alert_finalize_adm)};
		return options;
	}
	
	protected CharSequence[] getOptionsRenewAppointmentMenu(){
		CharSequence[] optionsRenew = {getString(R.string.alert_edit_adm), getString(R.string.alert_duplicate_adm), getString(R.string.alert_remove_adm), getString(R.string.alert_cancel_adm), getString(R.string.alert_finalize_adm), getString(R.string.alert_renew_adm)};
		return optionsRenew;
	}

	protected CharSequence[] getOptionsPostponeAppointmentMenu(){
		CharSequence[] optionsRenew = {getString(R.string.alert_edit_adm), getString(R.string.alert_duplicate_adm), getString(R.string.alert_remove_adm), getString(R.string.alert_cancel_adm), getString(R.string.alert_finalize_adm), getString(R.string.alert_postpone_adm)};
		return optionsRenew;
	}
	
	public void prepareToPersist(){

	}
	public void prepareToUpdate(){
		
	}
	
	public Boolean getEnabled() {
		Boolean enabled = getIntent().getBooleanExtra(ENABLED, false);
		if (enabled != null)
			return enabled;
		return false;
	}
	
	public void init() {
		Boolean duplicate = null;
		if (service != null){
			id = getIntent().getLongExtra(service.getColumnHack(), 0);
			duplicate = getIntent().getBooleanExtra(DUPLICATE, false);
		}
		this.prepareComponents();
		this.prepareList();
		if (id != null && id > 0){
			loadInstance();
			if (duplicate != null && duplicate)id=null;
		} else {
			createInstance();
		}
			
	}
	
	@Override
	public void setServiceInstance(IGenericService<E> instance) {
		this.service = instance;
	}
	
	public GenericActivity(Class<E> clazz) {
		this.clazz = clazz;
	}
	
	public void setInstance(E instance) {
		this.instance = instance;
	}
	
	public E getInstance() {
		if (instance == null)
			instance = createInstance();
		return instance;
	}
	
	protected E loadInstance(){
		createInstance();
		if (id != null)
			instance = service.selectById(id);
		return instance;
	}
	
	public E createInstance(){
		try {
			if (clazz != null)
				instance = clazz.newInstance();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return instance;
	}
	
    protected void openView(Context context, Class<?> clazz, boolean finish){
    	this.finalize = finish;
    	startActivity(new Intent(context, clazz));
    	if (finish)finish();
    }
    
	public void callContactListFromPhone(int requestCode){
		startActivityForResult(new Intent(Intent.ACTION_PICK, android.provider.ContactsContract.Contacts.CONTENT_URI), requestCode);
	}
    
    protected void duplicate(Class<?> $class, String pkName, Long id, Integer resIdComingFrom){
    	if (id != null && id > 0 && pkName != null && !pkName.isEmpty()){
    		Intent intent = new Intent(this, $class);
    		intent.putExtra(pkName, id);
    		intent.putExtra(DUPLICATE, true);
    		intent.putExtra(ENABLED, true);
    		if (resIdComingFrom != null && resIdComingFrom > 0){
    			intent.putExtra(Util.COMING_FROM, resIdComingFrom);
    		}
    		startActivity(intent);
    		finish();
    	}
    }
    
	protected void loadInstance(Class<?> $class, String pkName, Long id, Boolean fieldEnabled, Integer resIdComingFrom) {
		if (id != null && id > 0 && pkName != null && !pkName.isEmpty()){
			Intent intent = new Intent(this, $class);
			intent.putExtra(pkName, id);
			if (resIdComingFrom != null && resIdComingFrom > 0){
				intent.putExtra(Util.COMING_FROM, resIdComingFrom);
			}
			if (fieldEnabled != null)
				intent.putExtra(ENABLED, fieldEnabled);
			startActivity(intent);
			finish();
		}
	}
	
    protected SharedPreferences getPreferences(Context context){
    	SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
    	return preferences;
    }
    
    protected ListView newListView(int id){
    	ListView listView = (ListView) findViewById(id);
    	return listView;
    }
    
	protected E getEntitySelected() {
		@SuppressWarnings("unchecked")
		E entity = (E) listView.getItemAtPosition(dataSelected);
		return entity;
	}
	
	public ListView getListView() {
		return listView;
	}
	
	public void setListView(ListView listView) {
		this.listView = listView;
	}
    
	protected AlertDialog createDialog(String title, OnClickListener event, CharSequence... options) {
		final CharSequence[] items = options;
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		if (title != null && !title.isEmpty())
			builder.setTitle(title);
		if (items != null && items.length > 0)
			builder.setItems(items, event);
		return builder.create();
	}
	
	protected AlertDialog createDialogYesNo(DialogInterface.OnClickListener instance) {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setPositiveButton(getString(R.string.alert_yes), instance);
		builder.setNegativeButton(getString(R.string.alert_no), instance);
		return builder.create();
	}

	protected AlertDialog createDialogOk(DialogInterface.OnClickListener instance) {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setNeutralButton("Ok",instance);
		return builder.create();
	}
	
	protected CharSequence[] getEditRemove(String editLabel, String removeLabel) {
		CharSequence options[] = {editLabel, removeLabel};
		return options;
	}
	
	public void sendMail(String[] to, String[] cc, String subject, String message, Context context) {
		try {
			Intent emailIntent = new Intent(Intent.ACTION_SEND);
			emailIntent.setData(Uri.parse("mailto:"));
			emailIntent.putExtra(Intent.EXTRA_EMAIL, to);
			if (cc != null)
				emailIntent.putExtra(Intent.EXTRA_CC, cc);
			emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
			emailIntent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(message));
			emailIntent.setType("text/html");
			context.startActivity(Intent.createChooser(emailIntent, "Email"));
		} catch (Exception e){
			util.showToastMessageLong(e.getMessage(), context);
			e.printStackTrace();
		}
	}
	
	public void sendSimpleMail(String to, String subject, String message, Context context){
		String[] email = {to};
		this.sendMail(email, new String[0], subject, message, context);
	}
	
	protected void sendSMSAuto(String number, String message){
		SmsManager smsManager = SmsManager.getDefault();
	    smsManager.sendTextMessage(number, null, message, null, null);
	}
	
	public void sendWhatsAppMessage(Activity appActivity, String texto) {

	    Intent sendIntent = new Intent(Intent.ACTION_SEND);     
	    sendIntent.setType("text/plain");
	    sendIntent.putExtra(android.content.Intent.EXTRA_TEXT, texto);

	    PackageManager pm = appActivity.getApplicationContext().getPackageManager();
	    final List<ResolveInfo> matches = pm.queryIntentActivities(sendIntent, 0);
	    boolean temWhatsApp = false;
	    for (final ResolveInfo info : matches) {
	      if (info.activityInfo.packageName.startsWith("com.whatsapp"))  {
	          final ComponentName name = new ComponentName(info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
	          sendIntent.addCategory(Intent.CATEGORY_LAUNCHER);
	          sendIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_NEW_TASK);
	          sendIntent.setComponent(name);
	          temWhatsApp = true;
	          break;
	      }
	    }               

	    if(temWhatsApp) {
	        appActivity.startActivity(sendIntent);
	    } else {
	        Toast.makeText(appActivity, appActivity.getString(R.string.noWhatsAppMessage), Toast.LENGTH_SHORT).show();
	    }
	}
	
	protected void sendSMSByApp(String number, String message){
		Intent smsIntent = new Intent(Intent.ACTION_VIEW);
		smsIntent.setType("vnd.android-dir/mms-sms");
		smsIntent.putExtra("address", number);
		smsIntent.putExtra("sms_body",message);
		startActivity(smsIntent);
	}
	
	protected void showProgressBar(Context context, String message){
		DataphoneAsyncTask task = new DataphoneAsyncTask(context);
		if (task != null){
			if (message != null && !message.isEmpty())
				task.setMessage(message);
			task.execute();
		}
	}
	
	@Override
	public void saveOrUpdate(View v) {
		if (id == null || id == 0){
			this.persist(v);
		} else {
			this.update(v);
		}
	}
	
	@Override
	public void persist(View v)  {
		this.showProgressBar(GenericActivity.this, getString(R.string.msg_saving));
		prepareToPersist();
		try {
			if (super.persist(instance))
				this.afterPersist();
		} catch (Exception e){
			e.printStackTrace();
		}
	}

	@Override
	public void update(View v) {
		this.showProgressBar(GenericActivity.this, getString(R.string.msg_updating));
		prepareToUpdate();
		try {
			if (super.update(instance, id))
				this.afterUpdate();
		} catch (Exception e){
			String error = getString(R.string.msg_persistence_error);
			util.showToastMessageLong(error+" "+e.getMessage(), this);
		}
	}
	
	public Long getId() {
		return id;
	}
	
	public void setId(Long id) {
		this.id = id;
	}

	@Override
	public void afterPersist() {
		util.showToastMessage(R.string.msg_data_registered, this);
	}

	@Override
	public void afterUpdate() {
		util.showToastMessage(R.string.msg_data_updated, this);		
	}
	@Override
	public void prepareList() {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void prepareComponents() {
		// TODO Auto-generated method stub
		
	}
	
	private static final String CALCULATOR_PACKAGE_NAME = "com.android.calculator2";
	private static final String CALCULATOR_CLASS_NAME = "com.android.calculator2.Calculator";

	public void launchCalculator() {
		Intent intent = new Intent();
		intent.setAction(Intent.ACTION_MAIN);
		intent.addCategory(Intent.CATEGORY_LAUNCHER);
		intent.setComponent(new ComponentName(CALCULATOR_PACKAGE_NAME, CALCULATOR_CLASS_NAME));
		try {
			startActivity(intent);
		} catch (ActivityNotFoundException noSuchActivity) {
			noSuchActivity.printStackTrace();
		}
	}
	
	public Boolean getFinalize() {
		return finalize;
	}
	
	public void setFinalize(Boolean finalize) {
		this.finalize = finalize;
	}
}
